/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Presentacion;

import AccesoADatos.GlobalException;
import AccesoADatos.NoDataException;
import AccesoADatos.ServicioUsuario;
import Logica.Clasificacion;
import Logica.Rol;
import Logica.Usuario;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DropMode;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Fernando
 */
public class Users extends javax.swing.JPanel {

    /**
     * Creates new form Users
     */
    private Conectado cnx;
    public ArrayList<Usuario> usuarios;
    public ArrayList<Rol> roles;
    public ArrayList<Rol> rolesUsuario;
    private Principal p;
    private String rol;
    public ArrayList<Clasificacion> clasificaciones;

    public Users(Conectado cnx, Principal principal) throws GlobalException, NoDataException {

        initComponents();
        rol = "a";
        this.p = principal;
        usuarios = new ArrayList();
        roles = new ArrayList();
        rolesUsuario = new ArrayList();
        this.cnx = cnx;
        userTF.setEditable(false);
        cargarArchivo();
        cargarTablaCategorias();
        rolesUsuarioTabla.setToolTipText("Right click to remove category.");
        cargarUsuarios();
        cargarTabla();


    }

    public void cargarArchivo() {
        Clasificacion c = null;
        try {
            FileInputStream fileIn = new FileInputStream("catalog.txt");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            ArrayList<Clasificacion> cla;
            cla = (ArrayList<Clasificacion>) in.readObject();
            if (cla != null) {
                clasificaciones = cla;
            }
            in.close();
            fileIn.close();
        } catch (IOException i) {
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException e) {
            System.out.println("Clasificacion class not found");
            e.printStackTrace();
            return;
        }
    }

    public void guardarArchivo() {
        try {
            FileOutputStream fileOut =
                    new FileOutputStream("catalog.txt");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);

            out.writeObject(clasificaciones);

            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in catalog.txt");
        } catch (IOException i) {
            i.printStackTrace();
        }

    }

    private void cargarRolesUsuario(Usuario u) throws GlobalException, NoDataException {
        ServicioUsuario su = new ServicioUsuario(cnx.getConexion().user, cnx.getConexion().pass, cnx.getConexion().ip, cnx.getConexion().port, cnx.getConexion().db);
        ArrayList<String> lis = (ArrayList<String>) su.listarRolesDeUsuario(u);
        for (int i = 0; i < lis.size(); i++) {
            rolesUsuario.add(new Rol(lis.get(i)));
        }
    }

    private void cargarTablaRolesUsuario() {
        for (int i = 0; i < ((DefaultTableModel) rolesUsuarioTabla.getModel()).getRowCount();) {
            ((DefaultTableModel) rolesUsuarioTabla.getModel()).removeRow(i);
        }

        //agrega lo que haya en el arraylist
        for (int i = 0; i < rolesUsuario.size(); i++) {
            Rol r = rolesUsuario.get(i);
            ((DefaultTableModel) rolesUsuarioTabla.getModel()).addRow(new Object[]{r.getRol()});
        }
        ((DefaultTableModel) rolesUsuarioTabla.getModel()).addRow(new Object[]{""});
        rolesUsuario.clear();
    }

    private void cargarTablaRoles() {
        for (int i = 0; i < ((DefaultTableModel) tablaRoles.getModel()).getRowCount();) {
            ((DefaultTableModel) tablaRoles.getModel()).removeRow(i);
        }

        //agrega lo que haya en el arraylist
        for (int i = 0; i < roles.size(); i++) {
            Rol r = roles.get(i);
            ((DefaultTableModel) tablaRoles.getModel()).addRow(new Object[]{r.getRol()});
        }
    }

    private void cargarRoles() throws GlobalException, NoDataException {
        ServicioUsuario su = new ServicioUsuario(cnx.getConexion().user, cnx.getConexion().pass, cnx.getConexion().ip, cnx.getConexion().port, cnx.getConexion().db);
        ArrayList<String> lis = (ArrayList<String>) su.listarRoles();
        System.out.print(lis.size());
        for (int i = 0; i < lis.size(); i++) {
            roles.add(new Rol(lis.get(i)));
        }
    }

    private void cargarUsuarios() throws GlobalException, NoDataException {
        ServicioUsuario su = new ServicioUsuario(cnx.getConexion().user, cnx.getConexion().pass, cnx.getConexion().ip, cnx.getConexion().port, cnx.getConexion().db);
        ArrayList<String> lis = (ArrayList<String>) su.listarUsers();
        Iterator it = lis.iterator();
        Usuario newUser;
        while (it.hasNext()) {
            newUser = new Usuario((String) it.next());
            usuarios.add(newUser);
        }


        //JOptionPane.showMessageDialog(null, usuarios.toString());
        cargarTabla();



    }

    public void cargarTablaCategorias() {

        //borra toda la tabla primero
        for (int i = 0; i < ((DefaultTableModel) tablaRoles.getModel()).getRowCount();) {
            ((DefaultTableModel) tablaRoles.getModel()).removeRow(i);
        }

        //agrega lo que haya en el arraylist
        for (int i = 0; i < clasificaciones.size(); i++) {
            Clasificacion c = clasificaciones.get(i);
            ((DefaultTableModel) tablaRoles.getModel()).addRow(new Object[]{c.getClasificacion()/*,c.getDescripcion()*/});
        }
    }

    private void cargarTabla() {

        //borra toda la tabla primero
        for (int i = 0; i < ((DefaultTableModel) getjTable1().getModel()).getRowCount();) {
            ((DefaultTableModel) getjTable1().getModel()).removeRow(i);
        }

        //agrega lo que haya en el arraylist
        for (int i = 0; i < usuarios.size(); i++) {
            Usuario r = usuarios.get(i);
            ((DefaultTableModel) usersTable.getModel()).addRow(new Object[]{r.getName()});
        }

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tUsers = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        usersTable = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        tablaRoles = new javax.swing.JTable();
        newUser = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        userTF = new javax.swing.JTextField();
        jScrollPane3 = new javax.swing.JScrollPane();
        rolesUsuarioTabla = new javax.swing.JTable();
        jLabel3 = new javax.swing.JLabel();
        delete = new javax.swing.JButton();

        tUsers.setText("Users Catalog");

        usersTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Users"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        usersTable.setDragEnabled(true);
        usersTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                usersTableMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(usersTable);

        jLabel1.setText("Categories");

        tablaRoles.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Category"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tablaRoles.setDragEnabled(true);
        tablaRoles.setDropMode(javax.swing.DropMode.INSERT_ROWS);
        tablaRoles.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                tablaRolesMousePressed(evt);
            }
        });
        jScrollPane2.setViewportView(tablaRoles);

        newUser.setBackground(new java.awt.Color(255, 255, 255));
        newUser.setText("New User");
        newUser.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newUserActionPerformed(evt);
            }
        });

        jLabel2.setText("User:");

        userTF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                userTFActionPerformed(evt);
            }
        });

        rolesUsuarioTabla.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Category"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        rolesUsuarioTabla.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                rolesUsuarioTablaMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                rolesUsuarioTablaMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                rolesUsuarioTablaMouseReleased(evt);
            }
        });
        jScrollPane3.setViewportView(rolesUsuarioTabla);
        rolesUsuarioTabla.getColumnModel().getColumn(0).setResizable(false);

        jLabel3.setText("Current Categories");

        delete.setBackground(new java.awt.Color(255, 255, 255));
        delete.setText("Delete User");
        delete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(20, 20, 20)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(tUsers)
                        .addGap(167, 167, 167))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 230, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 324, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(userTF, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 432, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(newUser)
                                .addGap(27, 27, 27)
                                .addComponent(delete)))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(tUsers)
                .addComponent(jLabel1))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(newUser)
                    .addComponent(delete))
                .addGroup(layout.createSequentialGroup()
                    .addGap(13, 13, 13)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 628, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(userTF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel2))
                    .addGap(24, 24, 24)
                    .addComponent(jLabel3)
                    .addGap(20, 20, 20)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 524, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void userTFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_userTFActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_userTFActionPerformed

    private void usersTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_usersTableMouseClicked
        int index = usersTable.getSelectedRow();
        rol = "";
        Usuario u = new Usuario(usersTable.getModel().getValueAt(index, 0) + "");
        userTF.setText(u.getName());

        try {
            cargarRolesUsuario(u);
            cargarTablaRolesUsuario();
        } catch (GlobalException e) {
            for (int i = 0; i < ((DefaultTableModel) rolesUsuarioTabla.getModel()).getRowCount();) {
                ((DefaultTableModel) rolesUsuarioTabla.getModel()).removeRow(i);
            }
            JOptionPane.showMessageDialog(this, "Cannot load user's roles", "Warning", JOptionPane.ERROR_MESSAGE);
            ((DefaultTableModel) rolesUsuarioTabla.getModel()).addRow(new Object[]{""});
        } catch (NoDataException ex) {
            for (int i = 0; i < ((DefaultTableModel) rolesUsuarioTabla.getModel()).getRowCount();) {
                ((DefaultTableModel) rolesUsuarioTabla.getModel()).removeRow(i);
            }
            //JOptionPane.showMessageDialog(this, "", "Warning", JOptionPane.ERROR_MESSAGE);
            System.out.println("No hay categorias");
            ((DefaultTableModel) rolesUsuarioTabla.getModel()).addRow(new Object[]{""});
        }
    }//GEN-LAST:event_usersTableMouseClicked

    private void newUserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newUserActionPerformed
        // TODO add your handling code here:
        newUser cu = new newUser(this.cnx, this.p);
        cu.setVisible(true);
        //this.p.validate();
    }//GEN-LAST:event_newUserActionPerformed

    private void deleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteActionPerformed
        // TODO add your handling code here:
        String user = userTF.getText();
        boolean prueba = buscar(user);
        if (prueba) {
            try {
                Object[] options = {"Yes", "No"};
                int op = JOptionPane.showOptionDialog(this, "Are you sure you want to delete user " + user + "?", "Drop User", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);

                if (op == 0) {
                    ServicioUsuario su = new ServicioUsuario(cnx.getConexion().user, cnx.getConexion().pass, cnx.getConexion().ip, cnx.getConexion().port, cnx.getConexion().db);
                    su.dropUser(user);
                    usuarios.clear();
                    cargarUsuarios();
                    cargarTabla();
                    userTF.setText("");
                    JOptionPane.showMessageDialog(null, "User successfully removed.");
                } else {
                    JOptionPane.showMessageDialog(null, "User not removed.");
                }
            } catch (GlobalException ex) {
                Logger.getLogger(Users.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoDataException ex) {
                Logger.getLogger(Users.class.getName()).log(Level.SEVERE, null, ex);
            }


        } else {
            JOptionPane.showMessageDialog(this, "This user does not exist.", "Warning", JOptionPane.ERROR_MESSAGE);

        }

    }//GEN-LAST:event_deleteActionPerformed

    private void tablaRolesMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tablaRolesMousePressed
        // TODO add your handling code here:
        int row = tablaRoles.rowAtPoint(evt.getPoint());
        rol = (String) tablaRoles.getValueAt(row, 0);
        //JOptionPane.showMessageDialog(this, rol);
    }//GEN-LAST:event_tablaRolesMousePressed

    private void rolesUsuarioTablaMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_rolesUsuarioTablaMousePressed
        // TODO add your handling code here:
    }//GEN-LAST:event_rolesUsuarioTablaMousePressed

    private void rolesUsuarioTablaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_rolesUsuarioTablaMouseClicked
        if (evt.isMetaDown()) {

            int r = rolesUsuarioTabla.rowAtPoint(evt.getPoint());
            String elim = (String) rolesUsuarioTabla.getValueAt(r, 0);
            if (elim.equals("")) {
                JOptionPane.showMessageDialog(this, "This row is empty.", "Warning", JOptionPane.ERROR_MESSAGE);
            } else {
                Object[] options = {"Yes", "No"};
                int op = JOptionPane.showOptionDialog(this, "Are you sure you want to remove " + elim + " to " + userTF.getText() + "?", "Remove Category", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
                if (op == 0) {
                    ServicioUsuario su2 = new ServicioUsuario(this.cnx.getConexion().user, this.cnx.getConexion().pass, this.cnx.getConexion().ip, this.cnx.getConexion().port, this.cnx.getConexion().db);
                    boolean aux;

                    try {
                        //JOptionPane.showMessageDialog(this, "REVOKE " + elim + " FROM " + userTF.getText());
                        aux = su2.removeCategoryFromUser(elim, userTF.getText());
                        if (aux) {

                            ((DefaultTableModel) rolesUsuarioTabla.getModel()).removeRow(r);
                            JOptionPane.showMessageDialog(this, "Category removed.");
                        }
                    } catch (GlobalException ex) {
                        JOptionPane.showMessageDialog(this, "It can be removed.", "Warning", JOptionPane.ERROR_MESSAGE);
                    } catch (NoDataException ex) {
                        JOptionPane.showMessageDialog(this, "It can be removed.", "Warning", JOptionPane.ERROR_MESSAGE);
                    }


                } else {
                    JOptionPane.showMessageDialog(this, "The category has not been removed");
                }
            }
        } else {
            ServicioUsuario su = new ServicioUsuario(this.cnx.getConexion().user, this.cnx.getConexion().pass, this.cnx.getConexion().ip, this.cnx.getConexion().port, this.cnx.getConexion().db);
            if (!(rol.equals(""))) {
                boolean finder = buscar(userTF.getText());
                if (finder) {
                    //JOptionPane.showMessageDialog(null,rolesUsuarioTabla.getRowCount());
                    boolean noRepetido = this.buscarRolNuevo();
                    if (noRepetido) {

                        boolean success = false;

                        Object[] options = {"Yes", "No"};
                        int op = JOptionPane.showOptionDialog(this, "Are you sure you want to add " + rol + " to " + userTF.getText() + "?", "Asign Category", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
                        if (op == 0) {
                            try {
                                success = su.newRolToUser(rol, userTF.getText());
                                rolesUsuarioTabla.getModel().setValueAt(rol, rolesUsuarioTabla.getRowCount() - 1, 0);
                                ((DefaultTableModel) rolesUsuarioTabla.getModel()).addRow(new Object[]{""});
                            } catch (GlobalException ex) {
                            } catch (NoDataException ex) {
                            }
                            JOptionPane.showMessageDialog(this, "The category has been assigned");
                        } else {
                            JOptionPane.showMessageDialog(this, "The category has not been assigned");
                        }

                        rol = "";
                    } else {
                        JOptionPane.showMessageDialog(this, "This user already has this category.", "Warning", JOptionPane.ERROR_MESSAGE);
                    }
                } else {
                    JOptionPane.showMessageDialog(this, "This user does not exist.", "Warning", JOptionPane.ERROR_MESSAGE);
                }
            }
        }

    }//GEN-LAST:event_rolesUsuarioTablaMouseClicked

    private void rolesUsuarioTablaMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_rolesUsuarioTablaMouseReleased
        // TODO add your handling code here:
        //JOptionPane.showMessageDialog(this, rol);
    }//GEN-LAST:event_rolesUsuarioTablaMouseReleased
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton delete;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JButton newUser;
    private javax.swing.JTable rolesUsuarioTabla;
    private javax.swing.JLabel tUsers;
    private javax.swing.JTable tablaRoles;
    private javax.swing.JTextField userTF;
    private javax.swing.JTable usersTable;
    // End of variables declaration//GEN-END:variables

    /**
     * @return the jTable1
     */
    public javax.swing.JTable getjTable1() {
        return usersTable;
    }

    /**
     * @param jTable1 the jTable1 to set
     */
    public void setjTable1(javax.swing.JTable jTable1) {
        this.usersTable = jTable1;
    }

    public boolean buscar(String n) {

        for (int i = 0; i < usuarios.size(); i++) {
            if (n.equals(usuarios.get(i).getName())) {
                return true;
            }
        }
        return false;
    }

    public boolean buscarRolNuevo() {
        for (int i = 0; i < ((DefaultTableModel) rolesUsuarioTabla.getModel()).getRowCount(); i++) {

            String n = (String) ((DefaultTableModel) rolesUsuarioTabla.getModel()).getValueAt(i, 0);
            if (n.equals(rol)) {
                return false;
            }
        }
        return true;
    }
}
